<template>
	<form class="px-[35px]" @submit.prevent="onEnter">
		<input type="submit" class="hidden" />
		<base-icon
			name="back2"
			class="text-[20px] absolute left-3 top-3 cursor-pointer"
			@click="onBack" />
		<base-icon
			name="close"
			class="text-[20px] absolute right-3 top-3 cursor-pointer"
			@click="onClose" />
		<div class="h-12 mt-[50px] mb-4 pt-[12px] app-font-bold text-center text-[20px]">
			{{ $t('register.third.completeNow') }}
		</div>
		<base-tip class="mb-4">
			<i18n-t keypath="register.third.subtitle" scope="global">
				<span style="text-transform: capitalize">
					{{ accountStore.thirdCallbackParams?.source }}
				</span>
				<span>{{ accountStore.thirdPartyInfo?.email }}</span>
			</i18n-t>
		</base-tip>
		<base-input
			label-t="account.username"
			v-model="formValue.username"
			:name="FormFieldName.username"
			:autofocus="isPC()"
			:errorT="formRule.username.result.textT"
			:is-danger="!formRule.username.result.valid"
			@blur="checkExists('username')"
			@focus="formReset('username')" />
		<base-input
			label-t="register.invitationCodeOptional"
			:placeholder="tInput('register.invitationCode')"
			expandable
			v-model="formValue.inviteCode"
			v-model:expanded="expandedInviteCode"
			:name="FormFieldName.inviteCode"
			click-expanded-with-label
			:errorT="formRule.inviteCode.result.textT"
			:is-danger="!formRule.inviteCode.result.valid"
			@blur="formRule.inviteCode.validator()"
			@focus="formReset('inviteCode')" />
		<base-button type="primary" :loading="loading" @click="onEnter">
			{{ $t('region.submit') }}
		</base-button>
	</form>
</template>

<script setup lang="ts">
import { computed, nextTick, reactive, ref } from 'vue'
import { BaseButton, BaseIcon, BaseInput, BaseTip } from '@/components/base'
import { checkUsername } from '@/api/account.ts'
import { useAccountStore, useAppStore } from '@/store'
import { isInviteCode, isLength, isPC, isUsername, tInput } from '@/utils'
import { AccountShowType, Action } from '@/types'
import { useRequest } from '@/hooks'
import { FormFieldName } from '@/enums'

type RuleType = {
	text?: string
	textT?: string
	valid: boolean
	rules?: RuleType[]
}

const accountStore = useAccountStore()
const appStore = useAppStore()
const expandedInviteCode = ref(!!appStore.agent?.inviteId)

const formValue = reactive({
	username: '',
	inviteCode: appStore.agent?.inviteId ?? ''
})
const formRule = reactive({
	username: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.username.result = { valid: true })
			if (action === Action.input) formRule.username.hasInput = true
			if (action === Action.blur && !formRule.username.hasInput) return
			const value = formValue.username
			let msg = ''
			if (!value) {
				msg = 'register.usernameRuleRequired'
			} else if (!isUsername(value)) {
				msg = 'register.usernameRuleChar'
			} else if (!isLength(value, action === Action.input ? 0 : 3, 16)) {
				msg = 'register.usernameRuleLength'
			} else if (!/[a-zA-Z]/.test(value)) {
				msg = 'register.usernameRuleLetter'
			}
			formRule.username.result = { textT: msg, valid: !msg }
		}
	},
	inviteCode: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.inviteCode.result = { valid: true })
			if (action === Action.input) formRule.inviteCode.hasInput = true
			if (action === Action.blur && !formRule.inviteCode.hasInput) return
			const value = formValue.inviteCode
			let msg = ''
			if (!value) {
				// 非必填
			} else if (!isLength(value, 1, 30)) {
				msg = 'register.invitationCodeRuleLength'
			} else if (!isInviteCode(value)) {
				msg = 'register.invitationCodeInvalid'
			}
			formRule.inviteCode.result = { textT: msg, valid: !msg }
		}
	}
})

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}

const checkExists = async (type: keyof typeof formRule) => {
	setTimeout(async () => {
		if (accountStore.accountShow !== AccountShowType.thirdRegister) return
		const value = String(formValue[type])
		formRule[type]?.validator?.(Action.submit)
		if (formRule[type].result?.valid && value) {
			if (type === 'username') {
				const { data } = await checkUsername(value)
				if (!data) {
					formRule[type].result = { valid: false, textT: 'register.usernameExists' }
				}
			}
		}
	}, 1)
}

const submitDisabled = computed(
	() => !formValue.username || Object.values(formRule).some(({ result: { valid } }) => !valid)
)

const onBack = () => accountStore.showAccount(AccountShowType.login)
const onClose = () => accountStore.showAccount(AccountShowType.none)

const { run, loading } = useRequest(accountStore.thirdRegister, { showError: true })

const onSubmit = () => {
	run({
		// userId: null,
		authId: accountStore.thirdPartyInfo?.authId || null,
		source: accountStore.thirdPartyInfo?.source || null,
		email: accountStore.thirdPartyInfo?.email || null,
		username: formValue.username.trim().toLowerCase() || null,
		inviteCode: formValue.inviteCode.trim() || null
	})
}

const onEnter = () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	nextTick(() => {
		if (submitDisabled.value) return
		onSubmit()
	})
}
</script>

<style scoped></style>
